[CSR]在CSR8675的Source工程实现串口收发实例

您所在的位置:网站首页 蓝牙 8675 8761 [CSR]在CSR8675的Source工程实现串口收发实例

[CSR]在CSR8675的Source工程实现串口收发实例

2023-05-31 21:35| 来源: 网络整理| 查看: 265

最近在做一个source工程项目,主要是实现将I2S的音频通过蓝牙发射出去,串口作为控制外扩芯片的接口,真是困难重重啊,只想吐槽下ADK的功能强大,但是难用的特色(个人观点)。

因为CSR在source工程中已经封装了任务Task,所以就不能安装裸跑的方式,简单实现收发,而是需要注册任务的方式实现:

但是考虑到只有MessageSinkTask函数,所以这样写:

void uartStreamInit(void) { /* Assign task message handler */ theUARTStreamTask.task.handler = uart_stream_handler; StreamConfigure(VM_STREAM_UART_CONFIG, VM_STREAM_UART_THROUGHPUT); /* Configure uart settings */ StreamUartConfigure(VM_UART_RATE_57K6, VM_UART_STOP_ONE, VM_UART_PARITY_NONE); /* Get the source for the uart */ theUARTStreamTask.uart_source = StreamUartSource(); if(theUARTStreamTask.uart_source != 0) PanicNull(theUARTStreamTask.uart_source); /* Register uart source with task */ MessageSinkTask(StreamSinkFromSource(theUARTStreamTask.uart_source), &theUARTStreamTask.task); }

而发送接收则参考网上的同志写为:

static void uartSendData(uint8 *buf, uint16 len) { uint16 offset; uint8 *dest; /*get the sink for the uart, panic if not available*/ Sink sink = StreamUartSink(); PanicNull(sink); /*claim space in the sink, getting the offset to it*/ offset = SinkClaim(sink, len); if(offset == 0xFFFF) Panic(); /*space not available*/ /*Map the sink into memory space*/ dest = SinkMap(sink); (void)PanicNull(dest); /*copy the string into the claimed space*/ memcpy(dest + offset, buf, len); /*Flush the data out to the uart*/ PanicZero(SinkFlush(sink, len)); } /*static uint8 uartRecvData(uint8* dataBuff,uint8 len)*/ static uint8 uartRecvData(void) { /* uint8 i = 0;uint8 tempBuff[]="test...";*/ uint8 ret = 0; Source src = StreamUartSource(); uint8 recvLen = SourceSize(src); uint8*recvPtr = (uint8*)SourceMap(src); if(recvLen > 0 && needRecv == 1){ if(recvLen >= UART_RECV_BUF_SIZE){ memcpy(&uartRecvBuf[uartRecvLen],recvPtr,UART_RECV_BUF_SIZE-1); uartRecvLen = UART_RECV_BUF_SIZE; }else{ memcpy(&uartRecvBuf[uartRecvLen],recvPtr,recvLen); uartRecvLen += recvLen; } needRecv = 0; } if(recvLen == 1 && needRecv == 0 && *recvPtr == '@'){ uartRecvBuf[0] = *recvPtr; uartRecvLen = 1; needRecv = 1; } SourceDrop(src,recvLen); /*parse and handle data*/ if(uartRecvLen >= UART_RECV_BUF_SIZE){ /*uartSendData(uartRecvBuf,UART_RECV_BUF_SIZE);*/ memset(uartRecvBuf,0,sizeof(uartRecvBuf)); uartRecvLen = 0; } return ret; } static void uart_stream_handler(Task t, MessageId id, Message payload) { switch(id) { case MESSAGE_MORE_DATA: { uartRecvData(); } break; default: break; } }

定义:

typedef struct { TaskData task; Task client; Source uart_source; unsigned uart_src_need_drop:1; uint8* pUartSrcStart; uint8* pUartSrcEnd; uint16 send_packet_length; }UARTStreamTask_t; #define UART_RECV_BUF_SIZE 8 static UARTStreamTask_t theUARTStreamTask; static uint8 uartRecvBuf[UART_RECV_BUF_SIZE] = {0}; static uint8 uartRecvLen = 0; static uint8 needRecv = 0;

调用初始化函数:

int main(void) { sourceAhiInit(&theSource->ahiTask); ChargerConfigure(CHARGER_SUPPRESS_LED0, TRUE); if(sourceAhiGetAppMode() == ahi_app_mode_configuration){ states_set_state(SOURCE_STATE_CONFIGURE_MODE); }else{ states_set_state(SOURCE_STATE_INITIALISING); } uartStreamInit(); MessageLoop(); return 0; }

需要注意的是,在ADK中编译下载后,需要通过pstool工具配置几个pskey值:因为用的是VM_STREAM_UART_CONFIG,所以要通过pstool配置Host interface为VM access to the UART:

当然还有波特率:

校验要求:无校验

将transport改成Raw

 

配置完成后需要在ADK中,reset,然后点击运行才能正常工作。

当然如果你觉得调试比较麻烦,也可以将这些参数写到默认的配置中:因为source工程中有个默认的psr配置文件,会随着ADK调试将配置写人:

// PSKEY_USR0 - Company ID &028a = 0000 0a12 // PSKEY_DEVICE_NAME - QTIL Audio Dongle &0108 = 5451 4c49 4120 6475 6f69 6420 6e6f 6c67 65 // PSKEY_LOCAL_SUPPORTED_FEATURES - Default &00ef - // PSKEY_HOST_INTERFACE - USB &01f9 = 0004 // PSKEY_UART_CONFIG_USR &01c2 = 0880 // PSKEY_UART_BAUDRATE baud 57600 &01ea = E100 ...

重新编译再烧写,就不用再次配置了。

补充说明:

调试发现不关接收的数据为多少,只要大于2Byte,必会收到两包数据,第一包一直为1byte,第二包为剩下的字节格式,有兴趣的同胞可以进去跟一下代码,我想的方法是拼凑的方式,即接收的数据以‘@’开头为起始,第二包为有效的解析数据。至于原因有可能是利用一个字节告知你数据已经到来,也可能是没有用流控的原因。如果有大师找到原因还请告知。

 

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3